var windowWidth = $(window).width();
var windowHeight = $(window).height();
var imgRound1 = new Image();
var imgRound2 = new Image();
var gammaNum = 0;

$('.game').append('<canvas width="'+windowWidth+'" height="'+windowHeight+'"></canvas>')

var app = {
    canvas: null,
    ctx: null,
    canvas2: null,
    ctx2: null,
    colors: {
        sky: "#D4F5FE",
        mountains: "#83CACE",
        ground: "#8FC04C",
        groundDark: "#73B043",
        road: "#606a7c",
        roadLine: "#FFF",
        hud: "#FFF"
    },
    settings: {
        fps: 60,
        skySize: windowHeight/2,
        ground: {
            size: windowWidth,
            min: 4,
            max: 120
        },
        road: {
            min: (windowWidth+100)/10,
            max: windowWidth+100,
        }
    },
    state: {
        bgpos: 0,
        offset: 0,
        startDark: true,
        curve: 0,
        currentCurve: 0,
        turn: 1,
        speed: 0,
        xpos: 0,
        section: 50,
        car: {
            maxSpeed: 50,
            friction: 0.4,
            acc: 0.85,
            deAcc: 0.5
        },
        keypress: {
            up: false,
            left: false,
            right: false,
            down: false
        }
    },
    storage: {
        bg: null
    }
};
app.canvas = document.getElementsByTagName('canvas')[0];
app.ctx = app.canvas.getContext('2d');
app.canvas2 = document.createElement('canvas');
app.canvas2.width = app.canvas.width;
app.canvas2.height = app.canvas.height;
app.ctx2 = app.canvas2.getContext('2d');
//window.addEventListener("keydown", keyDown, false);
//window.addEventListener("keyup", keyUp, false);
window.addEventListener("deviceorientation", orientationHandler, false);//devicemotion

//drawBg();
draw();


var fps = 60;
var now;
var then = Date.now();
var interval = 1000 / fps;
var delta;
var point,point2,point3;
var startPoint,endPoint;
var radian;
var move0, newCurve = 0;
var basePos = 0;
var carWidth = 160,
    carHeight = 120,
    carX = (app.canvas.width / 2) - (carWidth / 2),
    carY = windowHeight-140;

function tick() {
    requestAnimationFrame(tick);
    now = Date.now();
    delta = now - then;
    if (delta > interval) {
        then = now - (delta % interval);
        draw();
    }
}
tick();

function draw() {
    //setTimeout(function() {
    app.ctx.clearRect(0,windowHeight/2,windowWidth,windowHeight/2);
    app.ctx2.clearRect(0,windowHeight/2,windowWidth,windowHeight/2);
    calcMovement();

    // if(app.state.speed > 0) {
    //   app.state.bgpos += (app.state.currentCurve * 0.02) * (app.state.speed * 0.2);
    //   app.state.bgpos = app.state.bgpos % app.canvas.width;
    //
    //   app.ctx.putImageData(app.storage.bg, app.state.bgpos, 5);
    //   app.ctx.putImageData(app.storage.bg, app.state.bgpos > 0 ? app.state.bgpos - app.canvas.width : app.state.bgpos + app.canvas.width, 5);
    // }

    app.state.offset += app.state.speed * 0.05;
    if(app.state.offset > app.settings.ground.min) {
        app.state.offset = app.settings.ground.min - app.state.offset;
        app.state.startDark = !app.state.startDark;
    }
    //drawCar();
    drawGround(app.ctx, app.state.offset, app.colors.ground, app.colors.groundDark, app.canvas.width);

    drawRoad(app.settings.road.min + 6, app.settings.road.max + 36, 10, app.colors.roadLine);
    drawGround1(app.ctx2, app.state.offset, app.colors.roadLine, app.colors.road, app.canvas.width);
    drawRoad(app.settings.road.min, app.settings.road.max, 10, app.colors.road);
    drawRoad(3, 24, 0, app.ctx.createPattern(app.canvas2, 'repeat'));

    drawHUD(app.ctx, 70, 70, app.colors.hud);
    //window.requestAnimationFrame(draw);
    //}, 1000 / app.settings.fps);
}

function drawHUD(ctx, centerX, centerY, color) {
    var radius = 40, tigs = [0, 90, 135, 180, 225, 270, 315],
        angle = 90;

    ctx.beginPath();
    ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    ctx.lineWidth = 4;
    ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
    ctx.fill();
    ctx.strokeStyle = color;
    ctx.stroke();

    for (var i = 0; i < tigs.length; i++) {
        drawTig(ctx, centerX, centerY, radius, tigs[i], 7);
    }

    // draw pointer
    angle = map(app.state.speed, 0, app.state.car.maxSpeed, 90, 360);
    drawPointer(app.ctx, color, 50, 70, 70, angle);
}

function drawPointer(ctx, color, radius, centerX, centerY, angle) {
    point = getCirclePoint(centerX, centerY, radius - 20, angle);
        point2 = getCirclePoint(centerX, centerY, 2, angle + 90);
        point3 = getCirclePoint(centerX, centerY, 2, angle - 90);

    ctx.beginPath();
    ctx.strokeStyle = "#FF9166";
    ctx.lineCap = 'round';
    ctx.lineWidth = 4;
    ctx.moveTo(point2.x, point2.y);
    ctx.lineTo(point.x, point.y);
    ctx.lineTo(point3.x, point3.y);
    ctx.stroke();

    ctx.beginPath();
    ctx.arc(centerX, centerY, 9, 0, 2 * Math.PI, false);
    ctx.fillStyle = color;
    ctx.fill();
}

function drawTig(ctx, x, y, radius, angle, size) {
    startPoint = getCirclePoint(x, y, radius - 4, angle);
    endPoint = getCirclePoint(x, y, radius - size, angle)

    ctx.beginPath();
    ctx.lineCap = 'round';
    ctx.moveTo(startPoint.x, startPoint.y);
    ctx.lineTo(endPoint.x, endPoint.y);
    ctx.stroke();
}

function getCirclePoint(x, y, radius, angle) {
    radian = (angle / 180) * Math.PI;

    return {
        x: x + radius * Math.cos(radian),
        y: y + radius * Math.sin(radian)
    }
}

function calcMovement() {
    move = app.state.speed * 0.01;
    newCurve = 0;

    //if(app.state.keypress.up) {
        app.state.speed += app.state.car.acc - (app.state.speed * 0.015);
    //} else if (app.state.speed > 0) {
        //app.state.speed -= app.state.car.friction;
    //}

    // if(app.state.keypress.down && app.state.speed > 0) {
    //     app.state.speed -= 1;
    // }

    // Left and right
    app.state.xpos -= (app.state.currentCurve * app.state.speed) * 0.005;

    if(app.state.speed) {
        if(app.state.keypress.left) {
            app.state.xpos += (Math.abs(app.state.turn) + 7 + (app.state.speed > app.state.car.maxSpeed / 4 ? (app.state.car.maxSpeed - (app.state.speed / 2)) : app.state.speed)) * 0.2;
            app.state.turn -= 1;
        }

        if(app.state.keypress.right) {
            app.state.xpos -= (Math.abs(app.state.turn) + 7 + (app.state.speed > app.state.car.maxSpeed / 4 ? (app.state.car.maxSpeed - (app.state.speed / 2)) : app.state.speed)) * 0.2;
            app.state.turn += 1;
        }

        if(app.state.turn !== 0 && !app.state.keypress.left && !app.state.keypress.right) {
            app.state.turn += app.state.turn > 0 ? -0.25 : 0.25;
        }
    }

    app.state.turn = clamp(app.state.turn, -5, 5);
    app.state.speed = clamp(app.state.speed, 0, app.state.car.maxSpeed);

    // section
    app.state.section -= app.state.speed;

    // if(app.state.section < 0) {
    //   app.state.section = randomRange(1000, 9000);
    //
    //   newCurve = randomRange(-50, 50);
    //
    //   if(Math.abs(app.state.curve - newCurve) < 20) {
    //     newCurve = randomRange(-50, 50);
    //   }
    //
    //   app.state.curve = newCurve;
    // }

    if(app.state.currentCurve < app.state.curve && move < Math.abs(app.state.currentCurve - app.state.curve)) {
        app.state.currentCurve += move;
    } else if(app.state.currentCurve > app.state.curve && move < Math.abs(app.state.currentCurve - app.state.curve)) {
        app.state.currentCurve -= move;
    }

    if(Math.abs(app.state.xpos) > 550) {
        app.state.speed *= 0.96;
    }

    app.state.xpos = clamp(app.state.xpos, -650, 650);
}

function keyUp(e) {
    move(e, false);
}

function keyDown(e) {
    move(e, true);
}

function orientationHandler(e) {
    gammaNum = e.gamma;
    if (gammaNum < -30){
        app.state.keypress.left = true;
    }else if (gammaNum > 30) {
        app.state.keypress.right = true;
    }else{
        app.state.keypress.left = false;
        app.state.keypress.right = false;
    }
};

function move(e, isKeyDown) {
    if(e.keyCode >= 37 && e.keyCode <= 40) {
        e.preventDefault();
    }

    if(e.keyCode === 37) {
        app.state.keypress.left = isKeyDown;
    }

    if(e.keyCode === 38) {
        app.state.keypress.up = isKeyDown;
    }

    if(e.keyCode === 39) {
        app.state.keypress.right = isKeyDown;
    }

    if(e.keyCode === 40) {
        app.state.keypress.down = isKeyDown;
    }
}

function randomRange(min, max) {
    return min + Math.random() * (max - min);
}

function norm(value, min, max) {
    return (value - min) / (max - min);
}

function lerp(norm, min, max) {
    return (max - min) * norm + min;
}

function map(value, sourceMin, sourceMax, destMin, destMax) {
    return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
}

function clamp(value, min, max) {
    return Math.min(Math.max(value, min), max);
}

function drawBg() {

    //app.ctx.fillStyle = app.colors.sky;
    //app.ctx.fillRect(0, 0, app.canvas.width, app.settings.skySize);
    var img=new Image();
    img.src="images/cd3.png";
    img.onload = function(){
        console.log('图片加载成功');
        console.log(this);
        app.ctx.drawImage(img,0, 0, app.canvas.width, app.settings.skySize);
    }
    //drawMountain(0, 60, 200);
    //drawMountain(280, 40, 200);
    //drawMountain(400, 80, 200);
    //drawMountain(550, 60, 200);

    //app.storage.bg = app.ctx.getImageData(0, 0, app.canvas.width, app.canvas.height);
}

function drawMountain(pos, height, width) {
    app.ctx.fillStyle = app.colors.mountains;
    app.ctx.strokeStyle = app.colors.mountains;
    app.ctx.lineJoin = "round";
    app.ctx.lineWidth = 20;
    app.ctx.beginPath();
    app.ctx.moveTo(pos, app.settings.skySize);
    app.ctx.lineTo(pos + (width / 2), app.settings.skySize - height);
    app.ctx.lineTo(pos + width, app.settings.skySize);
    app.ctx.closePath();
    app.ctx.stroke();
    app.ctx.fill();
}

function drawSky() {
    app.ctx.fillStyle = app.colors.sky;
    app.ctx.fillRect(0, 0, app.canvas.width, app.settings.skySize);
}

function drawRoad(min, max, squishFactor, color) {
    basePos = app.canvas.width + app.state.xpos;

    app.ctx.fillStyle = color;
    app.ctx.beginPath();
    app.ctx.moveTo(((basePos + min) / 2) - (app.state.currentCurve * 3), app.settings.skySize);
    app.ctx.quadraticCurveTo((((basePos / 2) + min)) + (app.state.currentCurve / 3) + squishFactor, app.settings.skySize + 52, (basePos + max) / 2, app.canvas.height);
    app.ctx.lineTo((basePos - max) / 2, app.canvas.height);
    app.ctx.quadraticCurveTo((((basePos / 2) - min)) + (app.state.currentCurve / 3) - squishFactor, app.settings.skySize + 52, ((basePos - min) / 2) - (app.state.currentCurve * 3), app.settings.skySize);
    app.ctx.closePath();
    app.ctx.fill();
}

function drawCar() {


    // // shadow
    // roundedRect(app.ctx, "rgba(0, 0, 0, 0.35)", carX - 1 + app.state.turn, carY + (carHeight - 35), carWidth + 10, carHeight, 9);
    //
    // // tires
    // roundedRect(app.ctx, "#111", carX, carY + (carHeight - 30), 30, 40, 6);
    // roundedRect(app.ctx, "#111", (carX - 22) + carWidth, carY + (carHeight - 30), 30, 40, 6);
    //
    // drawCarBody(app.ctx);
}

function drawCarBody(ctx) {
    var startX = windowWidth/2-75, startY = windowHeight-110,
        lights = [10, 26, 134, 152],
        lightsY = 0;

    /* Front */
    roundedRect(app.ctx, "#C2C2C2", startX + 6 + (app.state.turn * 1.1), startY - 18, 146, 40, 18);

    ctx.beginPath();
    ctx.lineWidth="12";
    ctx.fillStyle="#FFFFFF";
    ctx.strokeStyle="#FFFFFF";
    ctx.moveTo(startX + 30, startY);
    ctx.lineTo(startX + 46 + app.state.turn, startY - 25);
    ctx.lineTo(startX + 114 + app.state.turn, startY - 25);
    ctx.lineTo(startX + 130, startY);
    ctx.fill();
    ctx.stroke();
    /* END: Front */

    ctx.lineWidth="12";
    ctx.lineCap = 'round';
    ctx.beginPath();
    ctx.fillStyle="#DEE0E2";
    ctx.strokeStyle="#DEE0E2";
    ctx.moveTo(startX + 2, startY + 12 + (app.state.turn * 0.2));
    ctx.lineTo(startX + 159, startY + 12 + (app.state.turn * 0.2));
    ctx.quadraticCurveTo(startX + 166, startY + 35, startX + 159, startY + 55 + (app.state.turn * 0.2));
    ctx.lineTo(startX + 2, startY + 55 - (app.state.turn * 0.2));
    ctx.quadraticCurveTo(startX - 5, startY + 32, startX + 2, startY + 12 - (app.state.turn * 0.2));
    ctx.fill();
    ctx.stroke();

    ctx.beginPath();
    ctx.lineWidth="12";
    ctx.fillStyle="#DEE0E2";
    ctx.strokeStyle="#DEE0E2";
    ctx.moveTo(startX + 30, startY);
    ctx.lineTo(startX + 40 + (app.state.turn * 0.7), startY - 15);
    ctx.lineTo(startX + 120 + (app.state.turn * 0.7), startY - 15);
    ctx.lineTo(startX + 130, startY);
    ctx.fill();
    ctx.stroke();

    roundedRect(ctx, "#474747", startX - 4, startY, 169, 10, 3, true, 0.2);
    roundedRect(ctx, "#474747", startX + 40, startY + 5, 80, 10, 5, true, 0.1);

    ctx.fillStyle = "#FF9166";

    lights.forEach(function(xPos) {
        ctx.beginPath();
        ctx.arc(startX + xPos, startY + 20 + lightsY, 6, 0, Math.PI*2, true);
        ctx.closePath();
        ctx.fill();
        lightsY += app.state.turn * 0.05;
    });

    ctx.lineWidth="9";
    ctx.fillStyle="#222222";
    ctx.strokeStyle="#444";

    roundedRect(app.ctx, "#FFF", startX + 60, startY + 25, 40, 18, 3, true, 0.05);
}

function roundedRect(ctx, color, x, y, width, height, radius, turn, turneffect) {
    var skew = turn === true ? app.state.turn * turneffect : 0;

    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.moveTo(x + radius, y - skew);

    // top right
    ctx.lineTo(x + width - radius, y + skew);
    ctx.arcTo(x + width, y + skew, x + width, y + radius + skew, radius);
    ctx.lineTo(x + width, y + radius + skew);

    // down right
    ctx.lineTo(x + width, (y + height + skew) - radius);
    ctx.arcTo(x + width, y + height + skew, (x + width) - radius, y + height + skew, radius);
    ctx.lineTo((x + width) - radius, y + height + skew);

    // down left
    ctx.lineTo(x + radius, y + height - skew);
    ctx.arcTo(x, y + height - skew, x, (y + height - skew) - radius, radius);
    ctx.lineTo(x, (y + height - skew) - radius);

    // top left
    ctx.lineTo(x, y + radius - skew);
    ctx.arcTo(x, y - skew, x + radius, y - skew, radius);
    ctx.lineTo(x + radius, y - skew);
    ctx.fill();
}

function drawGround1(ctx, offset, lightColor, darkColor, width) {
    var pos = (app.settings.skySize - app.settings.ground.min) + offset, stepSize = 1, drawDark = app.state.startDark, firstRow = true;
    ctx.fillStyle = lightColor;
    ctx.fillRect(0, app.settings.skySize, width, app.settings.ground.size);

    ctx.fillStyle =  darkColor;
    while(pos <= app.canvas.height) {
        stepSize = norm(pos, app.settings.skySize, app.canvas.height) * app.settings.ground.max;
        if(stepSize < app.settings.ground.min) {
            stepSize = app.settings.ground.min;
        }

        if(drawDark) {
            if(firstRow) {

                ctx.fillRect(0, app.settings.skySize, width, stepSize - (offset > app.settings.ground.min ? app.settings.ground.min : app.settings.ground.min - offset));
            } else {
                ctx.fillRect(0, pos < app.settings.skySize ? app.settings.skySize : pos, width, stepSize);
            }
        }

        firstRow = false;
        pos += stepSize;
        drawDark = !drawDark;
    }
}


function drawGround(ctx, offset, lightColor, darkColor, width) {
    var pos = (app.settings.skySize - app.settings.ground.min) + offset, stepSize = 1, drawDark = app.state.startDark, firstRow = true;
    // imgRound1.src="img/bg1-1.jpg";
    // ctx.drawImage(imgRound1,0,app.settings.skySize, width, app.settings.ground.size);
    // ctx.fillStyle = lightColor;
    // ctx.fillRect(0, app.settings.skySize, width, app.settings.ground.size);

    //ctx.fillStyle =  darkColor;
    imgRound2.src="img/bg1-2.png";
    while(pos <= app.canvas.height) {
        stepSize = norm(pos, app.settings.skySize, app.canvas.height) * app.settings.ground.max;
        if(stepSize < app.settings.ground.min) {
            stepSize = app.settings.ground.min;
        }

        if(drawDark) {
            if(firstRow) {
                ctx.drawImage(imgRound2,0, app.settings.skySize, width, stepSize - (offset > app.settings.ground.min ? app.settings.ground.min : app.settings.ground.min - offset));
                //ctx.fillRect(0, app.settings.skySize, width, stepSize - (offset > app.settings.ground.min ? app.settings.ground.min : app.settings.ground.min - offset));
            } else {
                ctx.drawImage(imgRound2,0, pos < app.settings.skySize ? app.settings.skySize : pos, width, stepSize);
                //ctx.fillRect(0, pos < app.settings.skySize ? app.settings.skySize : pos, width, stepSize);
            }
        }

        firstRow = false;
        pos += stepSize;
        drawDark = !drawDark;
    }
}